package Controller

import (
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"hr-system/Global"
	"hr-system/Model"
	response "hr-system/Response"
	"log"
	"strconv"
	"time"
)

type IReportManageController interface {
	ReportNew(c *gin.Context)
	ReportResign(c *gin.Context)
	ReportDepartment(c *gin.Context)
	ReportPost(c *gin.Context)
	ReportMonth(c *gin.Context)
}

type ReportManageController struct {
	DB *gorm.DB
}
func NewReportManageController() IReportManageController{
	db := Global.GetDB()
	return ReportManageController{DB: db}
}
//获取某一天的0点时间
func GetZeroTime(d time.Time) time.Time {
	return time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, d.Location())
}
//获取传入的时间所在月份的第一天，即某月第一天的0点。如传入time.Now(), 返回当前月份的第一天0点时间。
func GetFirstDateOfMonth(d time.Time) time.Time {
	d = d.AddDate(0, 0, -d.Day() + 1)
	return GetZeroTime(d)
}
//获取传入的时间所在月份的最后一天，即某月最后一天的0点。如传入time.Now(), 返回当前月份的最后一天0点时间。
func GetLastDateOfMonth(d time.Time) time.Time {
	return GetFirstDateOfMonth(d).AddDate(0, 1, -1)
}


func (r ReportManageController) ReportNew(c *gin.Context) {
	var requestD Model.Department
	_ = c.ShouldBind(&requestD)
	departmentName := requestD.DepartmentName
	var t Model.SETime
	_ = c.ShouldBind(&t)
	log.Println(t)
	s := t.StartDate
	e := t.EndDate
	log.Println(s,e)
	var startDate time.Time
	var endDate time.Time
	if s == "" {
		startDate = GetFirstDateOfMonth(time.Now())
	} else {
		startDate, _ = time.Parse("2006-01-02",s)
	}
	if e == "" {
		endDate = GetLastDateOfMonth(time.Now())
	} else {
		endDate, _ = time.Parse("2006-01-02", e)
	}
	log.Println(startDate, endDate)
	var records []Model.APIEmployee
	if departmentName == "" {
		r.DB.Model(&Model.Employee{}).
			Where("entry_date between ? and ? ",startDate,endDate).Find(&records)
	} else {
		var temp Model.Department
		r.DB.Model(&Model.Department{}).Where("department_name=?", departmentName).
			Find(&temp)
		r.DB.Model(&Model.Employee{}).
			Where("department_number=? and entry_date between ? and ? ",
				temp.DepartmentNumber, startDate, endDate).Find(&records)
	}
	// titles := []interface{}{"序号","部门名称","岗位名称","姓名","性别","入职日期","学历"}
	length := len(records)
	result := make([]Model.ResultEmployee, 0)
	for i:=0; i < length; i++ {
		record := records[i]
		var dpm Model.APIDepartment
		var post Model.APIPost
		r.DB.Model(&Model.Department{}).Where("department_number=?",
			record.DepartmentNumber).First(&dpm)
		r.DB.Model(&Model.Post{}).Where("department_number=? and post_number=?",
			record.DepartmentNumber,record.PostNumber).First(&post)
		dname, pname := dpm.DepartmentName, post.PostName
		result = append(result, Model.ResultEmployee {
			//No: i+1,
			Id: record.Id,
			DepartmentName: dname,
			PostName: pname,
			Name: record.Name,
			Sex: record.Sex,
			EntryDate: record.EntryDate.Format("2006-01-02"),
			HighestEducation: record.HighestEducation,
		})
	}
	response.Success(c, gin.H{"data":result}, "返回成功")
}

func (r ReportManageController) ReportResign(c *gin.Context) {
	var requestD Model.Department
	_ = c.ShouldBind(&requestD)
	departmentName := requestD.DepartmentName
	var t Model.SETime
	_ = c.ShouldBind(&t)
	s := t.StartDate
	e := t.EndDate
	var startDate time.Time
	var endDate time.Time
	if s == "" {
		startDate = GetFirstDateOfMonth(time.Now())
	} else {
		startDate, _ = time.Parse("2006-01-02",s)
	}
	if e == "" {
		endDate = GetLastDateOfMonth(time.Now())
	} else {
		endDate, _ = time.Parse("2006-01-02", e)
	}
	var records []Model.ResignedEmployee
	r.DB.Model(&Model.ResignedEmployee{}).
		Where("resignation_date between ? and ?",startDate,endDate).Find(&records)
	// titles := []interface{}{"序号","部门名称","岗位名称","姓名","性别","离职日期","离职原因"}
	length := len(records)
	result := make([]Model.ResultResigned, 0)
	for i:=0; i < length; i++ {
		record := records[i]
		var tmp Model.Employee
		r.DB.Model(&Model.Employee{}).Where("id=?",record.Id).First(&tmp)
		var dpm Model.APIDepartment
		var post Model.APIPost
		r.DB.Model(&Model.Department{}).Where("department_number=?",
			tmp.DepartmentNumber).First(&dpm)
		if departmentName != "" && dpm.DepartmentName != departmentName {
			continue
		}
		r.DB.Model(&Model.Post{}).Where("department_number=? and post_number=?",
			tmp.DepartmentNumber,tmp.PostNumber).First(&post)
		dname, pname := dpm.DepartmentName, post.PostName
		result = append(result, Model.ResultResigned{
			// No: i+1,
			DepartmentName: dname,
			PostName: pname,
			Name: tmp.Name,
			Sex: tmp.Sex,
			ResignationDate: record.ResignationDate.Format("2006-01-02"),
			ReasonsForResignation: record.ReasonsForResignation,
		})
	}
	response.Success(c, gin.H{"data":result}, "返回成功")
}

func (r ReportManageController) ReportDepartment(c *gin.Context) {
	var t Model.SETime
	_ = c.ShouldBind(&t)
	s := t.StartDate
	e := t.EndDate
	var startDate time.Time
	var endDate time.Time
	if s == "" {
		startDate = GetFirstDateOfMonth(time.Now())
	} else {
		startDate, _ = time.Parse("2006-01-02",s)
	}
	if e == "" {
		endDate = GetLastDateOfMonth(time.Now())
	} else {
		endDate, _ = time.Parse("2006-01-02", e)
	}
	var records []Model.DepartmentTransferEmployee
	r.DB.Model(&Model.DepartmentTransferEmployee{}).
		Where("transfer_date between ? and ?",startDate,endDate).Find(&records)
	// titles := []interface{}{"序号","原部门名称","新部门名称","姓名","性别","调动日期","调动原因"}
	length := len(records)
	result := make([]Model.ResultDepartmentTransfer, 0)
	for i:=0; i < length; i++ {
		record := records[i]
		var tmp Model.Employee
		r.DB.Model(&Model.Employee{}).Where("id=?",record.Id).First(&tmp)
		var newDpm Model.APIDepartment
		var originDpm Model.APIDepartment
		r.DB.Model(&Model.Department{}).Where("department_number=?",
			record.OriginDepartmentNumber).First(&originDpm)
		r.DB.Model(&Model.Department{}).Where("department_number=?",
			record.NewDepartmentNumber).First(&newDpm)
		result[i] = Model.ResultDepartmentTransfer{
			// No: i+1,
			OriginDepartmentName: originDpm.DepartmentName,
			NewDepartmentName: newDpm.DepartmentName,
			Name: tmp.Name,
			Sex: tmp.Sex,
			TransferDate: record.TransferDate.Format("2006-01-02"),
			ReasonsForTransfer: record.ReasonsForTransfer,
		}
	}
	response.Success(c, gin.H{"data":result}, "返回成功")
}

func (r ReportManageController) ReportPost(c *gin.Context) {
	var t Model.SETime
	_ = c.ShouldBind(&t)
	log.Println(t)
	s := t.StartDate
	e := t.EndDate
	var startDate time.Time
	var endDate time.Time
	if s == "" {
		startDate = GetFirstDateOfMonth(time.Now())
	} else {
		startDate, _ = time.Parse("2006-01-02",s)
	}
	if e == "" {
		endDate = GetLastDateOfMonth(time.Now())
	} else {
		endDate, _ = time.Parse("2006-01-02", e)
	}
	var records []Model.PostTransferEmployee
	r.DB.Model(&Model.PostTransferEmployee{}).
		Where("transfer_date between ? and ?",startDate,endDate).Find(&records)
	// titles := []interface{}{"序号","部门名称","原岗位名称","新岗位名称","姓名","性别","调动日期","调动原因"}
	length := len(records)
	result := make([]Model.ResultPostTransfer, 0)
	for i:=0; i < length; i++ {
		record := records[i]
		var tmp Model.Employee
		r.DB.Model(&Model.Employee{}).Where("id=?",record.Id).First(&tmp)
		var dpm Model.APIDepartment
		var newPost Model.APIPost
		var originPost Model.APIPost
		r.DB.Model(&Model.Department{}).Where("department_number=?",
			tmp.DepartmentNumber).First(&dpm)
		r.DB.Model(&Model.Post{}).Where("department_number=? and post_number=?",
			tmp.DepartmentNumber,record.OriginPostNumber).First(&originPost)
		r.DB.Model(&Model.Post{}).Where("department_number=? and post_number=?",
			tmp.DepartmentNumber,record.NewPostNumber).First(&newPost)
		result[i] = Model.ResultPostTransfer{
			// No: i+1,
			DepartmentName: dpm.DepartmentName,
			OriginalPostName: originPost.PostName,
			NewPostName: newPost.PostName,
			Name: tmp.Name,
			Sex: tmp.Sex,
			TransferDate: record.TransferDate.Format("2006-01-02"),
			ReasonsForTransfer: record.ReasonsForTransfer,
		}
	}
	response.Success(c, gin.H{"data":result}, "返回成功")
}

func (r ReportManageController) ReportMonth(c *gin.Context) {
	m, _ := c.GetPostForm("month")
	if m == "" {
		m = time.Now().Format("2006-01-02")
	}
	month,_ := time.Parse("2006-01-02", m)
	s := GetFirstDateOfMonth(month).String()
	e := GetLastDateOfMonth(month).String()
	startDate, _ := time.Parse("2006-01-02",s)
	endDate, _ := time.Parse("2006-01-02", e)
	var records []Model.Department
	r.DB.Find(&records)
	titles := []interface{}{"部门名称","月初人数","月末人数","本月新入职","本月离职","本月调入","本月调出"}
	length := len(records)
	result := make([]Model.Monthly, 0)
	for i:=0; i < length; i++ {
		record := records[i]
		// 月初人数
		var firstDay int64
		r.DB.Model(&Model.Employee{}).
			Where("department_number=? and entry_date<? and is_quit='否'",
				record.DepartmentNumber,startDate).Count(&firstDay)
		// 月末人数
		var lastDay int64
		r.DB.Model(&Model.Employee{}).
			Where("department_number=? and entry_date<? and is_quit='否'",
				record.DepartmentNumber,endDate).Count(&lastDay)
		// 本月新聘人数
		var newIn int64
		r.DB.Model(&Model.Employee{}).
			Where("department_number=? and entry_date between ? and ?",
				record.DepartmentNumber,startDate,endDate).Count(&newIn)
		newResign := 0
		// 本月离职人数
		var selectResign []Model.ResignedEmployee
		r.DB.Model(&Model.ResignedEmployee{}).Where("resign_date between ? and ?",
			startDate,endDate).Find(&selectResign)
		cot := len(selectResign)
		for j:=0; j < cot; j++ {
			sr := selectResign[j]
			var temp Model.Employee
			r.DB.Model(&Model.Employee{}).Where("id=?",sr.Id).First(&temp)
			if temp.DepartmentNumber != record.DepartmentNumber {
				continue
			}
			newResign++
		}
		// 本月调入
		var newCome int64
		r.DB.Model(&Model.DepartmentTransferEmployee{}).
			Where("new_department_number=? and transfer_date between ? and ?",
				record.DepartmentNumber,startDate,endDate).Count(&newCome)
		// 本月调出
		var newGo int64
		r.DB.Model(&Model.DepartmentTransferEmployee{}).
			Where("origin_department_number=? and transfer_date between ? and ?",
				record.DepartmentNumber,startDate,endDate).Count(&newGo)
		result[i] = Model.Monthly{
			DepartmentName: record.DepartmentName,
			FirstDay:       strconv.FormatInt(firstDay, 10),
			LastDay:        strconv.FormatInt(lastDay, 10),
			NewIn:          strconv.FormatInt(newIn, 10),
			NewResign:      string(rune(newResign)),
			NewCome: 		strconv.FormatInt(newCome, 10),
			NewGo:          strconv.FormatInt(newGo, 10),
		}
	}
	response.Success(c, gin.H{"title": titles, "records":result}, "返回成功")}
